Load relevant packages
library(sf)
## Warning: package 'sf' was built under R version 4.4.1
## Linking to GEOS 3.11.0, GDAL 3.5.3, PROJ 9.1.0; sf_use_s2() is TRUE
library(terra)
## Warning: package 'terra' was built under R version 4.4.1
## terra 1.8.10
library(tmap)
## Warning: package 'tmap' was built under R version 4.4.1
library(spData) # new package - you'll likely need to install
## Warning: package 'spData' was built under R version 4.4.1
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.1 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.1
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ tidyr::extract() masks terra::extract()
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
Let’s talk about non-CRAN packages
# next line is commented out becasue you only need to install once
#install.packages("spDataLarge", repos = "https://nowosad.github.io/drat/", type = "source")
library(spDataLarge)
We’ll use this later
nz_elev = rast(system.file("raster/nz_elev.tif", package = "spDataLarge"))
tmap uses a similar “grammar of graphics” as
ggplot2
simple fill
# nz data comes from spData package
tm_shape(nz) +
tm_fill()
or…
tm_shape(nz) +
tm_borders()
Or layer two different symbologies
tm_shape(nz) +
tm_fill() +
tm_borders()
But keep in mind - ORDER MATTERS!!!
# flip the order to illustrate order matters
tm_shape(nz) +
tm_borders() +
tm_fill()
Add layers and assign your map to a variable
map_nz_base = tm_shape(nz) + tm_polygons()
map_nz_blue_dots = map_nz_base +
tm_shape(nz_height) + tm_dots(size = 0.25, fill = "blue")
What happened? Nothing
You can simply call the variable to plot it
map_nz_blue_dots
It can be useful to “reuse” the base of a map and add different layers.
WAIT - Let’s first break down this code
# reuse map_nz_base from above
map_nz_red_bubbles = map_nz_base +
tm_shape(nz_height) + tm_bubbles(size = "elevation",
fill = "darkred",
lwd = 0,
fill_alpha = .4)
map_nz_red_bubbles
Things to note: 1. dots vs. bubbles 2. fill
vs. col (read the documentation) 3. variables used to
change symbology are put inside ““: size = "elevation"
map <- base + layer_1 + layer_2 + aesthetic + function + layer_3
tm_shape(nz) + tm_polygons(fill = "Median_income")
Wait… how did it determine the breaks in the data to create the choropleth?
DON’T MAKE ASSUMPTIONS FOR THE DEFAULT BEHAIVOR!!!
Let’s create a new object that represents NZ’s territorial waters. Who want to help break down the code?
nz_water = st_union(nz) %>%
st_buffer(22200) %>%
st_cast(to = "LINESTRING")
How would we know what units the 22200 is in for the
buffer function?
Plot it to show our work
tm_shape(nz_water) + tm_lines()
First, the base map and elevation
map1 <- tm_shape(nz) + tm_polygons() +
tm_shape(nz_elev) + tm_raster(col_alpha = 0.7)
map1
Next, let’s setup the water boundaries
map2 <- tm_shape(nz_water) + tm_lines()
map2
Finally, we can symbolize the heighest points
map3 <- tm_shape(nz_height) + tm_symbols()
map3
And then put it all together…
map.all <- map1 + map2 + map3
map.all
From your readings: How to arrange multiple maps into a single plot
map.arr <- tmap_arrange(map1, map2, map3)
map.arr
Any issues here?
Let’s go through one-by-one. What are your expectations fior each???
ma1 = tm_shape(nz) + tm_polygons(fill = "red")
ma2 = tm_shape(nz) + tm_polygons(fill = "red", fill_alpha = 0.3)
ma3 = tm_shape(nz) + tm_polygons(col = "blue")
ma4 = tm_shape(nz) + tm_polygons(lwd = 3)
ma5 = tm_shape(nz) + tm_polygons(lty = 2)
ma6 = tm_shape(nz) + tm_polygons(fill = "red", fill_alpha = 0.3,
col = "blue", lwd = 3, lty = 2)
tmap_arrange(ma1, ma2, ma3, ma4, ma5, ma6)
Setting your own breaks
tm_shape(nz) + tm_polygons(fill = "Median_income")
tm_shape(nz) + tm_polygons(fill = "Median_income",
fill.scale = tm_scale(breaks = c(0, 30000, 40000, 50000)))
A different way: 10 breaks
tm_shape(nz) + tm_polygons(fill = "Median_income",
fill.scale = tm_scale(n = 10))
tm_shape(nz) + tm_polygons(fill = "Median_income",
fill.scale = tm_scale(values = "BuGn"))
## [cols4all] color palettes: use palettes from the R package cols4all. Run
## `cols4all::c4a_gui()` to explore them. The old palette name "BuGn" is named
## "brewer.bu_gn"
## Multiple palettes called "bu_gn" found: "brewer.bu_gn", "matplotlib.bu_gn". The first one, "brewer.bu_gn", is returned.
Let’s go one by one
tm_shape(nz) + tm_polygons(fill = "Median_income",
fill.scale = tm_scale_intervals(style = "equal", values = "BuGn"))
## [cols4all] color palettes: use palettes from the R package cols4all. Run
## `cols4all::c4a_gui()` to explore them. The old palette name "BuGn" is named
## "brewer.bu_gn"
## Multiple palettes called "bu_gn" found: "brewer.bu_gn", "matplotlib.bu_gn". The first one, "brewer.bu_gn", is returned.
tm_shape(nz) + tm_polygons(fill = "Median_income",
fill.scale = tm_scale_intervals(style = "jenks", values = "viridis"))
tm_shape(nz) + tm_polygons(fill = "Median_income",
fill.scale = tm_scale_intervals(style = "quantile", values = "brewer.purples", n = 5))
Let’s start simple: changing the title
legend_title = expression("Area (km"^2*")")
tm_shape(nz) +
tm_polygons(fill = "Land_area", fill.legend = tm_legend(title = legend_title))
A bit more complicated: title, orientation, and position
tm_shape(nz) +
tm_polygons(fill = "Land_area",
fill.legend = tm_legend(title = legend_title,
orientation = "landscape",
position = tm_pos_out("center", "bottom")))
## [plot mode] fit legend/component: Some legend items or map compoments do not
## fit well, and are therefore rescaled.
## ℹ Set the tmap option `component.autoscale = FALSE` to disable rescaling.
We can of course pick and choose: let’s keep the legend in “portrait mode”
tm_shape(nz) +
tm_polygons(fill = "Land_area",
fill.legend = tm_legend(title = legend_title,
position = tm_pos_out("center", "bottom")))
Lastly, we can use tmap modes to be more interactive if we want
tmap_mode(mode = "view")
## ℹ tmap mode set to "view".
tm_shape(nz) +
tm_polygons(fill = "Land_area",
fill.legend = tm_legend(title = legend_title,
position = tm_pos_out("center", "bottom")))
ttm()
## ℹ tmap mode set to "plot".
Try clicking on a feature - what happens?
There is a LOT more detail in your readings for today, which we’re going to leverage in your next activity:
./data/static_mapping/left_join(), most likely)
between spatial and tabular dataoh_places.gpkg)EVERYTHING NEEDS DONE PROGRAMMATICALLY REFERENCING DATA LOCATIONS IN THE REPO (YOU’LL SEE WHY LATER)
You have until ______________________: